package com.vercon.moensmart

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.os.Process
import android.provider.Settings
import android.text.TextUtils
import com.facebook.cache.disk.DiskCacheConfig
import com.facebook.common.logging.FLog
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.tencent.bugly.crashreport.CrashReport
import com.vercon.common.room.AppDataBase
import com.vercon.common.utils.LogUtils
import com.vercon.common.utils.MirrorDataStorage
import com.vercon.common.utils.TypefaceUtil
import com.vercon.common.wifi.EasyzcWifi
import com.vercon.moensmart.utils.ForegroundCallbacks
import com.vercon.moensmart.utils.LightHelper
import me.jessyan.autosize.AutoSizeConfig
import me.jessyan.autosize.unit.Subunits
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.io.IOException
import java.lang.reflect.Method

class MainApplication : Application() , ForegroundCallbacks.Listener{
    private val TAG = MainApplication::class.java.simpleName
    private val SYSTEM_NAVIGATION = "system_navigation"



    companion object{
        var activityCount = 0;
        var isLightKiller = false
        private lateinit var application: MainApplication
        fun getContext(): MainApplication {
            return application
        }
    }

    private lateinit var myAppDataBase: AppDataBase

    override fun onCreate() {
        super.onCreate()
        application = this

        isLightKiller = isLightKillerFun()
        initializeFresco()
        hookWebView()
        myAppDataBase = AppDataBase.Companion.getInstance(this)
        //对单位的自定义配置, 请在 App 启动时完成
        AutoSizeConfig.getInstance().unitsManager.supportSubunits = Subunits.MM

        AutoSizeConfig.getInstance()
            .setBaseOnWidth(true)
            .setDesignWidthInDp(1920)
            .setCustomFragment(true)
            .setLog(true)
        //全局字体
        TypefaceUtil.replaceSystemDefaultFont(this@MainApplication, "fonts/alibaba_puhuiti_regular.ttf")
        MirrorDataStorage.instance().initialize(this, packageName)

        initBugly()

        EasyzcWifi.Companion.get().register(this)

        //监听activity处于前端还是后端
        ForegroundCallbacks.init(this)
        ForegroundCallbacks.get()?.addListener(this)

        LightHelper.getInstance().initLightData()
    }



    fun getAppDataBaseInstance(): AppDataBase {
        return myAppDataBase
    }

    fun setVirtualKey(isChecked: Boolean) {
        Thread {
            LogUtils.d("setVirtualKey 显示虚拟键: $isChecked")
            val intent = Intent("com.xbh.action.HIDE_STATUS_BAR")
            intent.putExtra("hide", !isChecked) //true则隐藏，false则显示
            sendBroadcast(intent)
            Settings.System.putInt(contentResolver, SYSTEM_NAVIGATION, if (isChecked) 1 else 0)
        }.start()
    }

    private fun initializeFresco() {
        val cacheFile = File(Environment.getExternalStorageDirectory().absolutePath + File.separator + "FrescoCache")
        if (!cacheFile.exists()) {
            cacheFile.mkdirs()
        }
        Fresco.initialize(
            this, ImagePipelineConfig.newBuilder(this)
                .setMainDiskCacheConfig(
                    DiskCacheConfig.newBuilder(this) //磁盘缓存路径
                        .setBaseDirectoryPath(cacheFile)
                        .setMaxCacheSize((500 * 1024 * 1024).toLong())
                        .build()
                )
                .setDownsampleEnabled(true)
                .build()
        )
//        if (BuildConfig.DEBUG) {
//            FLog.setMinimumLoggingLevel(FLog.VERBOSE)
//        }
    }

    private fun initBugly() {
        val context = applicationContext
        // 获取当前包名
        val packageName = context.packageName
        // 获取当前进程名
        val processName: String? = getProcessName(Process.myPid())
        // 设置是否为上报进程
        val strategy: CrashReport.UserStrategy = CrashReport.UserStrategy(context)
        strategy.setUploadProcess(processName == null || processName == packageName)
        // 初始化Bugly b isDebug,true为正式版启用，false为测试版启用
        CrashReport.initCrashReport(context, "2aa46cf030", BuildConfig.DEBUG, strategy)
    }

    /**
     * 获取进程号对应的进程名
     *
     * @param pid 进程号
     * @return 进程名
     */
    private fun getProcessName(pid: Int): String? {
        var reader: BufferedReader? = null
        try {
            reader = BufferedReader(FileReader("/proc/$pid/cmdline"))
            var processName = reader.readLine()
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim { it <= ' ' }
            }
            return processName
        } catch (throwable: Throwable) {
            throwable.printStackTrace()
        } finally {
            try {
                reader?.close()
            } catch (exception: IOException) {
                exception.printStackTrace()
            }
        }
        return null
    }

    @SuppressLint("PrivateApi", "DiscouragedPrivateApi")
    fun hookWebView() {
        val sdkInt = Build.VERSION.SDK_INT
        try {
            val factoryClass = Class.forName("android.webkit.WebViewFactory")
            val field = factoryClass.getDeclaredField("sProviderInstance")
            field.isAccessible = true
            var sProviderInstance = field[null]
            if (sProviderInstance != null) {
                LogUtils.i(TAG, "sProviderInstance isn't null")
                return
            }
            val getProviderClassMethod: Method = if (sdkInt > 22) {
                factoryClass.getDeclaredMethod("getProviderClass")
            } else if (sdkInt == 22) {
                factoryClass.getDeclaredMethod("getFactoryClass")
            } else {
                LogUtils.i(TAG, "Don't need to Hook WebView")
                return
            }
            getProviderClassMethod.isAccessible = true
            val factoryProviderClass = getProviderClassMethod.invoke(factoryClass) as Class<*>
            val delegateClass = Class.forName("android.webkit.WebViewDelegate")
            val delegateConstructor = delegateClass.getDeclaredConstructor()
            delegateConstructor.isAccessible = true
            if (sdkInt < 26) { //低于Android O版本
                val providerConstructor = factoryProviderClass.getConstructor(delegateClass)
                providerConstructor.isAccessible = true
                sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance())
            } else {
                val chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD")
                chromiumMethodName.isAccessible = true
                var chromiumMethodNameStr = chromiumMethodName[null] as String
                val staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass)
                sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance())
            }
            if (sProviderInstance != null) {
                field["sProviderInstance"] = sProviderInstance
                LogUtils.i(TAG, "Hook success!")
            } else {
                LogUtils.i(TAG, "Hook failed!")
            }
        } catch (e: Throwable) {
            LogUtils.w(TAG, e.message)
        }
    }

    override fun onBecameForeground() {
        setVirtualKey(false)
    }

    override fun onBecameBackground() {
        setVirtualKey(true)
    }

    override fun onActivityCreated(activity: Activity?) {

    }

    override fun onActivityResumed(activity: Activity?) {
        setVirtualKey(false)
    }


    //宽度:1920 高度:984 密度:2.0 密度DPI:320   3568的
    //宽度:1280 高度:752 密度:1.0 密度DPI:160  199
    fun isLightKillerFun(): Boolean {
        val str = Build.DISPLAY
        LogUtils.e("str=$str")
        return if (str.contains("3568") || str.contains("A99")) { //这个k系列的
            LogUtils.e("这个K系列的")
            true
        } else {
            LogUtils.e("这个S系列的")
            false
        }
    }

}